home *** CD-ROM | disk | FTP | other *** search
/ Gigantic Games 2 / Gigantic Games 2.iso / pc / _w_ / wb_tetris / wbtris_1.4 / source / wbtris.c < prev    next >
C/C++ Source or Header  |  1994-12-23  |  65KB  |  1,891 lines

  1. /*
  2.    *******************************************************************************
  3.    *                                                                             *
  4.    *                                                                             *
  5.    *     WW            WW  BBBBBBBB  TTTTTTTTTT  RRRRRRRR   II     SSSSSSS       *
  6.    *     WW            WW  BB     BB     TT      RR     RR  II    SS     SS      *
  7.    *      WW    WW    WW   BB     BB     TT      RR     RR  II    SS             *
  8.    *      WW   WWWW   WW   BBBBBBB       TT      RR   RRR   II     SSSSSSS       *
  9.    *       WW WW  WW WW    BB    BB      TT      RRRRRR     II           SS      *
  10.    *       WWWW    WWWW    BB     BB     TT      RR   RR    II           SS      *
  11.    *        WWW    WWW     BB     BB     TT      RR    RR   II    SS     SS      *
  12.    *        WW      WW     BBBBBBBB      TT      RR     RR  II     SSSSSSS       *
  13.    *                                                                             *
  14.    *                                                                             *
  15.    *          COPYRIGHT © 1993 by Dirk Böhmer  ( medusa@uni-paderborn.de )       *
  16.    *                                                                             *
  17.    *                            & Ralf Pieper                                    *
  18.    *                                                                             *
  19.    *          All rights reserved.                                               *
  20.    *                                                                             *
  21.    *                                                                             *
  22.    *******************************************************************************
  23. */
  24.  
  25. #include "WBTRIS.h"
  26.  
  27. #define SHOWHISCORE TRUE
  28. #define SAVEHISCORE FALSE
  29. #define RIGHTFIELD TRUE
  30. #define LEFTFIELD FALSE
  31.  
  32. /*#define TEMPLATE "LEFT=LEFTEDGE/N/K,TOP=TOPEDGE/N/K,N=NAME/K,NOLOCK=NOLOCKNAME/K/S\
  33. ,NONEXT=SHOWNONEXT/K/S,NOLACE/K/S,LEVEL/N/K\
  34. ,PULLDOWNTICKS/N/K\
  35. ,R=MOVERIGHT/K,L=MOVELEFT/K,RR=ROTATERIGHT/K,RL=ROTATELEFT/K\
  36. ,D=MOVEDOWN/K,DQ=MOVEDOWNQUICK/K,TP=TWOPLAYER/K/S" */
  37.  
  38. #define TEMPLATE "LEFT=LEFTEDGE/N/K,TOP=TOPEDGE/N/K,N=NAME/K,NOLOCK=NOLOCKNAME/K/S\
  39. ,NONEXT=SHOWNONEXT/K/S,NOLACE/K/S,LEVEL/N/K\
  40. ,PULLDOWNTICKS/N/K\
  41. ,R=MOVERIGHT/K,L=MOVELEFT/K,RR=ROTATERIGHT/K,RL=ROTATELEFT/K\
  42. ,D=MOVEDOWN/K,DQ=MOVEDOWNQUICK/K"
  43.  
  44.  
  45. extern struct Image Pausebrush;
  46. extern struct Image logo;
  47.  
  48. extern struct Image Gruen;
  49. extern struct Image GruenWeiss;
  50. extern struct Image GruenWeissSchach;
  51. extern struct Image GruenWeissSchraeg;
  52. extern struct Image Schwarz;
  53. extern struct Image SchwarzGruen;
  54. extern struct Image SchwarzWeiss;
  55.  
  56. extern struct Image GruenNI;
  57. extern struct Image GruenWeissNI;
  58. extern struct Image GruenWeissSchachNI;
  59. extern struct Image GruenWeissSchraegNI;
  60. extern struct Image SchwarzNI;
  61. extern struct Image SchwarzGruenNI;
  62. extern struct Image SchwarzWeissNI;
  63.  
  64. char versionstring[] = "\0$VER: " PROG_NAME VERSION " " "von " AUTHOR;
  65.  
  66. UBYTE *CYCLELabels[] = {
  67.     (UBYTE *)"Pause",
  68.     (UBYTE *)"Go on",
  69.     NULL };
  70. ;
  71.  
  72. struct obj {
  73.   BOOL objData[4][4];
  74.   int color;
  75. };
  76.  
  77. struct obj objects[8];
  78.  
  79. struct obj2 {
  80.   BOOL objData[4][4];
  81.   int color;
  82. };
  83.  
  84. struct obj2 objects2[8];
  85.  
  86. int field[YSIZE+1][XSIZE+2] = {
  87.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  88.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  89.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  90.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  91.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  92.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  93.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  94.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  95.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  96.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  97.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  98.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  99.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  100.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  101.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  102.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  103.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  104.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  105.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  106.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  107.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  108.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  109.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  110.                         {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
  111.                      };
  112.  
  113. int field2[YSIZE+1][XSIZE+2] = {
  114.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  115.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  116.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  117.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  118.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  119.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  120.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  121.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  122.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  123.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  124.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  125.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  126.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  127.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  128.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  129.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  130.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  131.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  132.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  133.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  134.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  135.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  136.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  137.                         {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
  138.                      };
  139.  
  140. int            FieldsSpace = 125;
  141. short          LGXOS;
  142. short          LGYOS;
  143. short          BOXXSIZE;
  144. short          BOXYSIZE;
  145. short          NEXTXOFFSET;
  146. short          MAINXOFFSET;
  147. BOOL           UseLace = TRUE;
  148. BOOL           TwoPlayer = FALSE;
  149. short          boxxsize;
  150. short          boxysize;
  151. int            Highscore;
  152. int            Score = 0;
  153. int            Lines = 0;
  154. int            time = DEFAULTTICKS;
  155. int            oldtime = DEFAULTTICKS;
  156. int            x = XSIZE/2;
  157. int            y = 0;
  158. int            time2 = DEFAULTTICKS;
  159. int            oldtime2 = DEFAULTTICKS;
  160. int            x2 = XSIZE/2;
  161. int            y2 = 0;
  162. UWORD          CursorUp    = CURSOR_UP,    CursorUp2    = CURSOR_UP2;
  163. UWORD          CursorDown  = CURSOR_DOWN,  CursorDown2  = CURSOR_DOWN2;
  164. UWORD          CursorLeft  = CURSOR_LEFT,  CursorLeft2  = CURSOR_LEFT2;
  165. UWORD          CursorRight = CURSOR_RIGHT, CursorRight2 = CURSOR_RIGHT2;
  166. UWORD          NormalSpace = SPACE   ,     NormalSpace2 = SPACE2;
  167. UWORD          QuickSpace  = QUICKSPACE,   QuickSpace2  = QUICKSPACE2;
  168.  
  169. /* Timer */
  170. BYTE                 TimerError = 0 ,  TimerError2 = 0 ;
  171. struct MsgPort      *TimerMP = NULL , *TimerMP2 = NULL ;
  172. struct timerequest  *TimerIO = NULL , *TimerIO2 = NULL ;
  173. struct Message      *TimerMSG = NULL, *TimerMSG2 = NULL;
  174.  
  175. /* Options */
  176. char        Name[25];
  177. BOOL        SpacePressed = FALSE, SpacePressed2 = FALSE;
  178. BOOL        lockname = TRUE;
  179. BOOL        nextteil = TRUE;
  180. int         LevelOffset = 0;
  181. int         pulldownticks = 0;
  182. int         WBTRIS_Window_Top = MAINWINDOWTOP;
  183. int         WBTRIS_Window_Left= MAINWINDOWLEFT;
  184.  
  185. struct RastPort   *rp = NULL;
  186. struct Library    *IntuitionBase = NULL;
  187. struct Library    *KeymapBase    = NULL;
  188. struct Library    *IconBase      = NULL;
  189. struct Window     *window        = NULL;
  190. struct obj        *objptr        = NULL;
  191. struct obj        *nextptr       = NULL;
  192. struct obj2       *objptr2       = NULL;
  193. struct obj2       *nextptr2      = NULL;
  194. struct Screen     *myscreen      = NULL;
  195. struct TextFont   *font = NULL, *font2 = NULL;
  196.  
  197. int LineCounter = 0;
  198. int Level;
  199.  
  200. struct TextAttr helvetica13 = {"helvetica.font", 13, 0, 0};
  201. struct TextAttr topaz8 = {"topaz.font", 8, 0, 0};
  202.  
  203. APTR           VisualInfo = NULL;
  204. struct Gadget *TetrisGList = NULL;
  205. struct Gadget *TetrisGadgets[9];
  206. BOOL           vonoptions = TRUE;
  207.  
  208. int obj1 = 0;
  209. int obj2 = 0;
  210. int obj3 = 0;
  211. int obj4 = 0;
  212. int obj5 = 0;
  213. int obj6 = 0;
  214. int obj7 = 0;
  215.  
  216.  
  217.  
  218.  
  219. int wbmain(struct WBStartup *wbs)
  220. {
  221.    struct DiskObject *dobj = NULL;
  222.    char             **toolsarray;
  223.    char              *s = NULL;
  224.    char              *tail = NULL;
  225.  
  226.    if ((IconBase = OpenLibrary("icon.library", 37l)) == NULL)
  227.       exit(FALSE);
  228.  
  229.    CurrentDir(wbs->sm_ArgList->wa_Lock);
  230.    if (dobj = (struct DiskObject *) GetDiskObject(wbs->sm_ArgList->wa_Name)) {
  231.       toolsarray = (char **) dobj->do_ToolTypes;
  232.  
  233.       if (s = (char *) FindToolType(toolsarray, "LEFTEDGE"))
  234.          WBTRIS_Window_Left = atoi(s);
  235.       if (s = (char *) FindToolType(toolsarray, "TOPEDGE"))
  236.          WBTRIS_Window_Top = atoi(s);
  237.       if (s = (char *) FindToolType(toolsarray, "NAME"))
  238.          strcpy(Name, s);
  239.       if (s = (char *) FindToolType(toolsarray, "LOCKNAME")) {
  240.          if ((strcmp(s, "TRUE")) == NULL)
  241.             lockname = TRUE;
  242.          else
  243.             lockname = FALSE;
  244.       }
  245.       if (s = (char *) FindToolType(toolsarray, "SHOWNEXT")) {
  246.          if ((strcmp(s, "TRUE")) == NULL)
  247.             nextteil = TRUE;
  248.          else
  249.             nextteil = FALSE;
  250.       }
  251.       if (s = (char *) FindToolType(toolsarray, "USELACE")) {
  252.          if ((strcmp(s, "TRUE")) == NULL)
  253.             UseLace = TRUE;
  254.          else
  255.             UseLace = FALSE;
  256.       }
  257. /*      if (s = (char *) FindToolType(toolsarray, "TWOPLAYER")) {
  258.          if ((strcmp(s, "TRUE")) == NULL)
  259.             TwoPlayer = TRUE;
  260.          else
  261.             TwoPlayer = FALSE;
  262.       }
  263. */
  264.       if (s = (char *) FindToolType(toolsarray, "LEVEL"))
  265.          LevelOffset = atoi(s);
  266.       if (s = (char *) FindToolType(toolsarray, "PULLDOWNSPEED"))
  267.          pulldownticks = (20 - atoi(s))/2;
  268.  
  269.       if (s = (char *) FindToolType(toolsarray, "MOVERIGHT"))
  270.          CursorRight = strtol(s, &tail, 0);
  271.       if (s = (char *) FindToolType(toolsarray, "MOVELEFT"))
  272.          CursorLeft  = strtol(s, &tail, 0);
  273.       if (s = (char *) FindToolType(toolsarray, "ROTATERIGHT"))
  274.          CursorUp    = strtol(s, &tail, 0);
  275.       if (s = (char *) FindToolType(toolsarray, "ROTATELEFT"))
  276.          CursorDown  = strtol(s, &tail, 0);
  277.       if (s = (char *) FindToolType(toolsarray, "MOVEDOWN"))
  278.          NormalSpace = strtol(s, &tail, 0);
  279.       if (s = (char *) FindToolType(toolsarray, "MOVEDOWNQUICK"))
  280.          QuickSpace  = strtol(s, &tail, 0);
  281.  
  282.       FreeDiskObject(dobj);
  283.    }
  284.  
  285.    if (IconBase)
  286.       CloseLibrary(IconBase);
  287.    Real_Main();
  288.    return(0);
  289. }
  290.  
  291.  
  292.  
  293. int main(void)
  294. {
  295.    int            i;
  296. /*   long           options[15];*/
  297.    long           options[14];
  298.    struct RDArgs *args = NULL;
  299.  
  300.    for (i=0; i<14; i++)
  301.       options[i] = 0L;
  302.  
  303. /*   for (i=0; i<15; i++)
  304.       options[i] = 0L;
  305. */
  306.    args = ReadArgs(TEMPLATE, options, NULL);
  307.  
  308.    if (args) {
  309.       if (options[0])
  310.          WBTRIS_Window_Left = *(int *) options[0];
  311.       if (options[1])
  312.          WBTRIS_Window_Top = *(int *) options[1];
  313.       if (options[2])
  314.          strcpy(Name, (char *) options[2]);
  315.       if (options[3])
  316.          lockname = !options[3];
  317.       if (options[4])
  318.          nextteil = options[4];
  319.       if (options[5])
  320.          UseLace = !options[5];
  321.       if (options[6])
  322.          LevelOffset = *(int *) options[6];
  323.       if (options[7])
  324.          pulldownticks = (20 - *(int *) options[7])/2;
  325.       if (options[8])
  326.          CursorRight = (UWORD) strtol((char *) options[8], NULL, 0);
  327.       if (options[9])
  328.          CursorLeft = (UWORD) strtol((char *) options[9], NULL, 0);
  329.       if (options[10])
  330.          CursorUp = (UWORD) strtol((char *) options[10], NULL, 0);
  331.       if (options[11])
  332.          CursorDown = (UWORD) strtol((char *) options[11], NULL, 0);
  333.       if (options[12])
  334.          NormalSpace = (UWORD) strtol((char *) options[12], NULL, 0);
  335.       if (options[13])
  336.          QuickSpace = (UWORD) strtol((char *) options[13], NULL, 0);
  337. /*      if (options[14])
  338.          TwoPlayer = options[14];*/
  339.    }
  340.    if (args)
  341.       FreeArgs(args);
  342.  
  343.    Real_Main();
  344.    return(0);
  345. }
  346.  
  347.  
  348.  
  349. int Real_Main(void)
  350. {
  351.    struct IntuiMessage *imsg = NULL;
  352.    struct InputEvent    inputevent = {0};
  353.    struct Gadget       *gad = NULL;
  354.    LONG                 windowsignal, timersignal, timersignal2;
  355.    BOOL                 Done = FALSE;
  356.    APTR                *eventptr = NULL;
  357.    long                 mask;
  358.    struct I0ExtSer     *reply = NULL;
  359.    WORD                 Width, Height;
  360.  
  361.    InitObjects();
  362.    openall();                    /* open Fonts, Libraries, VisualInfo, etc*/
  363.  
  364.    if (UseLace) {
  365.       LGXOS = 5;
  366.       LGYOS = 0;
  367.       boxxsize = BOXXSIZE = 18;
  368.       boxysize = BOXYSIZE = 16;
  369.       NEXTXOFFSET = 14;
  370.       MAINXOFFSET = 122;
  371.    } else {
  372.       LGXOS = 15;
  373.       LGYOS = 15;
  374.       boxxsize = BOXXSIZE = 16;
  375.       boxysize = BOXYSIZE = 8;
  376.       NEXTXOFFSET = 155;
  377.       MAINXOFFSET = 252;
  378.    }
  379.  
  380.    if (TwoPlayer) {
  381.       Width = 2*(XSIZE*boxxsize) + 30 + MAINXOFFSET + FieldsSpace;
  382.       Height = YSIZE*boxysize + 15 + YOFFSET;
  383.    } else {
  384.       Width = XSIZE*boxxsize + 35 + MAINXOFFSET;
  385.       Height = YSIZE*boxysize + 15 + YOFFSET;
  386.    }
  387.  
  388.    gad = CreateAllGadgets(myscreen);
  389.  
  390.    window = OpenWindowTags(NULL,
  391.                             WA_Left,    WBTRIS_Window_Left,
  392.                             WA_Top,     WBTRIS_Window_Top,
  393.                             WA_Width,   Width,
  394.                             WA_Height,  Height,
  395.                             WA_ScreenTitle, "WBTRIS",
  396.                             WA_Title,   "WBTRIS  © 1993 by Dirk Böhmer & Ralf Pieper",
  397.                             WA_Flags,   WFLG_CLOSEGADGET | WFLG_ACTIVATE | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_RMBTRAP,
  398.                             WA_Gadgets, TetrisGList,
  399.                             WA_IDCMP,   BUTTONIDCMP | NUMBERIDCMP | IDCMP_REFRESHWINDOW | IDCMP_RAWKEY | IDCMP_CLOSEWINDOW
  400.                                       | WFLG_DEPTHGADGET | WFLG_SMART_REFRESH  | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW,
  401.                             TAG_DONE);
  402.  
  403.    if (window == NULL)
  404.       closeout("Can't open window",RETURN_FAIL);
  405.  
  406.    rp = window->RPort;
  407.    Level = LevelOffset;
  408.  
  409.    x = XSIZE/2 - 1;
  410.    oldtime = time = DEFAULTTICKS - Level*2;
  411.    nextptr = RandomObject(LEFTFIELD);
  412.    objptr = RandomObject(LEFTFIELD);
  413.    y = 0;
  414.    if (InFirstLine(objptr) == TRUE)
  415.       y = 1;
  416.    if (nextteil == TRUE)
  417.       Draw_NextObject(nextptr, LEFTFIELD);
  418.  
  419.    if (TwoPlayer) {
  420.       x2 = XSIZE/2 - 1;
  421.       oldtime2 = time2 = DEFAULTTICKS - Level*2;
  422.       nextptr2 = RandomObject(RIGHTFIELD);
  423.       objptr2 = RandomObject(RIGHTFIELD);
  424.       y2 = 0;
  425.       if (InFirstLine(objptr2) == TRUE)
  426.          y2 = 1;
  427.       if (nextteil == TRUE)
  428.          Draw_NextObject(nextptr2, RIGHTFIELD);
  429.    }
  430.  
  431.    GT_RefreshWindow( window, NULL );
  432.  
  433.    DrawWindow();
  434.  
  435.  
  436.    timersignal  = 1L << TimerMP->mp_SigBit;
  437.    windowsignal = 1L << window->UserPort->mp_SigBit;
  438.  
  439.    /* Initialize InputEvent structure (already cleared to 0) */
  440.    inputevent.ie_Class = IECLASS_RAWKEY;
  441.  
  442.    Highscore = Loadhiscore();
  443.  
  444.    GT_SetGadgetAttrs(TetrisGadgets[GD_HighscoreGadget], window, NULL,
  445.                           GTNM_Number, (ULONG)Highscore,
  446.                           TAG_END);
  447.    GT_SetGadgetAttrs(TetrisGadgets[GD_LevelGadget], window, NULL,
  448.                           GTNM_Number, (ULONG)Level, TAG_END);
  449.  
  450.    TimerIO->tr_node.io_Command = TR_ADDREQUEST;
  451.    TimerIO->tr_time.tv_secs = 0;
  452.    TimerIO->tr_time.tv_micro = time * 20000;
  453.    SendIO((struct IORequest *) TimerIO);
  454.  
  455.    if (TwoPlayer) {
  456.       timersignal2  = 1L << TimerMP2->mp_SigBit;
  457.       TimerIO2->tr_node.io_Command = TR_ADDREQUEST;
  458.       TimerIO2->tr_time.tv_secs = 0;
  459.       TimerIO2->tr_time.tv_micro = time2 * 20000;
  460.       SendIO((struct IORequest *) TimerIO2);
  461.    }
  462.  
  463.    while(!Done) {
  464.       if (TwoPlayer)
  465.          mask = Wait(timersignal | timersignal2 | windowsignal);
  466.       else
  467.          mask = Wait(timersignal | windowsignal);
  468.  
  469.       /*
  470.       ** Signal kommt vom Timer
  471.       */
  472.       if (mask & timersignal) {
  473.          while(reply = (struct I0ExtSer *)GetMsg(TimerMP))
  474.          {
  475.             /* we don't need these messages */
  476.          }
  477.          AbortIO((struct IORequest *) TimerIO);
  478.          WaitIO((struct IORequest *) TimerIO);
  479.          TimerIO->tr_node.io_Command = TR_ADDREQUEST;
  480.          TimerIO->tr_time.tv_secs = 0;
  481.          TimerIO->tr_time.tv_micro = time * 20000;
  482.          SendIO((struct IORequest *) TimerIO);
  483.          if (CollisionDown(objptr, field, x, y, LEFTFIELD) == FALSE) {
  484.             AbortIO((struct IORequest *) TimerIO);
  485.             WaitIO((struct IORequest *) TimerIO);
  486.             time = oldtime;
  487.             Done = GameOver(field, lockname);
  488.             if (Done == FALSE) {
  489.                objptr = nextptr;
  490.                nextptr = RandomObject(LEFTFIELD);
  491.                y = 0 ;
  492.                if (InFirstLine(objptr) == TRUE)
  493.                   y = 1;
  494.  
  495.                x = XSIZE/2 - 1;
  496.                ClearNextField(LEFTFIELD);
  497.                if (nextteil == TRUE)
  498.                   Draw_NextObject(nextptr, LEFTFIELD);
  499.             }
  500.          } else {
  501.             Draw_Object(x, y, objptr, FALSE, LEFTFIELD);
  502.             y = y + 1;
  503.             Draw_Object(x, y, objptr, TRUE, LEFTFIELD);
  504.          }
  505.       }
  506.  
  507.       /*
  508.       ** Signal kommt vom Timer2
  509.       */
  510.       if ((mask & timersignal2) && TwoPlayer) {
  511.          while(reply = (struct I0ExtSer *)GetMsg(TimerMP2))
  512.          {
  513.             /* we don't need these messages */
  514.          }
  515.          AbortIO((struct IORequest *) TimerIO2);
  516.          WaitIO((struct IORequest *) TimerIO2);
  517.          TimerIO2->tr_node.io_Command = TR_ADDREQUEST;
  518.          TimerIO2->tr_time.tv_secs = 0;
  519.          TimerIO2->tr_time.tv_micro = time2 * 20000;
  520.          SendIO((struct IORequest *) TimerIO2);
  521.          if (CollisionDown(objptr2, field2, x2, y2, RIGHTFIELD) == FALSE) {
  522.             AbortIO((struct IORequest *) TimerIO2);
  523.             WaitIO((struct IORequest *) TimerIO2);
  524.             time2 = oldtime2;
  525.             Done = GameOver(field2, lockname);
  526.             if (Done == FALSE) {
  527.                objptr2 = nextptr2;
  528.                nextptr2 = RandomObject(RIGHTFIELD);
  529.                y2 = 0 ;
  530.                if (InFirstLine(objptr2) == TRUE)
  531.                   y2 = 1;
  532.  
  533.                x2 = XSIZE/2 - 1;
  534.                ClearNextField(RIGHTFIELD);
  535.                if (nextteil == TRUE)
  536.                   Draw_NextObject(nextptr2, RIGHTFIELD);
  537.             }
  538.          } else {
  539.             Draw_Object(x2, y2, objptr2, FALSE, RIGHTFIELD);
  540.             y2 = y2 + 1;
  541.             Draw_Object(x2, y2, objptr2, TRUE, RIGHTFIELD);
  542.          }
  543.       }
  544.  
  545.       /*
  546.       ** Signal kommt von Gadgets, Fenster, Tasten, usw.
  547.       */
  548.       if (mask & windowsignal) {
  549.          while (imsg = (struct IntuiMessage *)GetMsg(window->UserPort)) {
  550.             switch(imsg->Class) {
  551.                case IDCMP_GADGETUP:
  552.                   gad = (struct Gadget *)imsg->IAddress;
  553.                   switch(gad->GadgetID) {
  554.                      case GD_PauseGadget:
  555.                         Done = Pause();
  556.                         break;
  557.  
  558.                      case GD_NewGadget:
  559.                         NewGame(field, FALSE, FALSE);
  560.                         break;
  561.  
  562.                      case GD_ShowScoreGadget:
  563.                         HideField();
  564.                         HiscoreList(Name, Level, Score, LineCounter, window->LeftEdge, window->TopEdge, SHOWHISCORE);
  565.                         ReDrawField(field, LEFTFIELD);
  566.                         ReDrawField(field2, RIGHTFIELD);
  567.                         break;
  568.  
  569.                      case GD_OptGadget:
  570.                         OpenOptions(window->LeftEdge, window->TopEdge);
  571.                         NewGame(field, FALSE, TRUE);
  572.                         break;
  573.  
  574.                      case GD_StatGadget:
  575.                         HideField();
  576.                         statistic(window->LeftEdge, window->TopEdge, obj1, obj2, obj3, obj4, obj5, obj6, obj7);
  577.                         ReDrawField(field, LEFTFIELD);
  578.                         ReDrawField(field2, RIGHTFIELD);
  579.                         break;
  580.                   }
  581.                   break;
  582.  
  583.                   case IDCMP_REFRESHWINDOW:
  584.                      /* This handling is REQUIRED with GadTools. */
  585.                      GT_BeginRefresh(window);
  586.                      GT_EndRefresh(window, TRUE);
  587.                      break;
  588.  
  589.                   case IDCMP_INACTIVEWINDOW:
  590.                      WaitForActivateWindow();
  591.                      break;
  592.  
  593.                   case IDCMP_CLOSEWINDOW:
  594.                      QuitGame();
  595.                      break;
  596.  
  597.                   case IDCMP_RAWKEY:
  598.                      inputevent.ie_Code = imsg->Code;
  599.                      inputevent.ie_Qualifier = imsg->Qualifier;
  600.  
  601.                      if (imsg->Code == CursorUp) {
  602.                         if (Rotate_Matrixl(objptr, field, x, y, LEFTFIELD)) {
  603.                            Rotate_Matrixr(objptr, field, x, y, LEFTFIELD);
  604.                            Draw_Object(x, y, objptr, FALSE, LEFTFIELD);
  605.                            Rotate_Matrixl(objptr, field, x, y, LEFTFIELD);
  606.                            Draw_Object(x, y, objptr, TRUE, LEFTFIELD);
  607.                         }
  608.                      } else {
  609.                      if (imsg->Code == CursorDown) {
  610.                         if (Rotate_Matrixr(objptr, field, x, y, LEFTFIELD)) {
  611.                            Rotate_Matrixl(objptr, field, x, y, LEFTFIELD);
  612.                            Draw_Object(x, y, objptr, FALSE, LEFTFIELD);
  613.                            Rotate_Matrixr(objptr, field, x, y, LEFTFIELD);
  614.                            Draw_Object(x, y, objptr, TRUE, LEFTFIELD);
  615.                         }
  616.                      } else {
  617.                      if (imsg->Code == CursorLeft) {
  618.                         if (CollisionLeft(objptr, field, x, y) == TRUE) {
  619.                            Draw_Object(x, y, objptr, FALSE, LEFTFIELD);
  620.                            x = x-1;
  621.                            Draw_Object(x, y, objptr, TRUE, LEFTFIELD);
  622.                         }
  623.                      } else {
  624.                      if (imsg->Code == CursorRight) {
  625.                         if (CollisionRight(objptr, field, x, y) == TRUE) {
  626.                            Draw_Object(x, y, objptr, FALSE, LEFTFIELD);
  627.                            x=x+1;
  628.                            Draw_Object(x, y, objptr, TRUE, LEFTFIELD);
  629.                         }
  630.                      } else {
  631.                      if (imsg->Code == NormalSpace) {
  632.                         if (!SpacePressed) {
  633.                            AbortIO((struct IORequest *) TimerIO);
  634.                            WaitIO((struct IORequest *) TimerIO);
  635.                            SpacePressed = TRUE;
  636.                            oldtime = time;
  637.                            time = pulldownticks;
  638.                         }
  639.                      } else {
  640.                      if (imsg->Code == QuickSpace) {
  641.                         AbortIO((struct IORequest *) TimerIO);
  642.                         WaitIO((struct IORequest *) TimerIO);
  643.                         oldtime = time;
  644.                         time = 0;
  645.                      } else {
  646.                      if (imsg->Code == CursorUp2) {
  647.                         if (Rotate_Matrixl(objptr2, field2, x2, y2, RIGHTFIELD)) {
  648.                            Rotate_Matrixr(objptr2, field2, x2, y2, RIGHTFIELD);
  649.                            Draw_Object(x2, y2, objptr2, FALSE, RIGHTFIELD);
  650.                            Rotate_Matrixl(objptr2, field2, x2, y2, RIGHTFIELD);
  651.                            Draw_Object(x2, y2, objptr2, TRUE, RIGHTFIELD);
  652.                         }
  653.                      } else {
  654.                      if (imsg->Code == CursorDown2) {
  655.                         if (Rotate_Matrixr(objptr2, field2, x2, y2, RIGHTFIELD)) {
  656.                            Rotate_Matrixl(objptr2, field2, x2, y2, RIGHTFIELD);
  657.                            Draw_Object(x2, y2, objptr2, FALSE, RIGHTFIELD);
  658.                            Rotate_Matrixr(objptr2, field2, x2, y2, RIGHTFIELD);
  659.                            Draw_Object(x2, y2, objptr2, TRUE, RIGHTFIELD);
  660.                         }
  661.                      } else {
  662.                      if (imsg->Code == CursorLeft2) {
  663.                         if (CollisionLeft(objptr2, field2, x2, y2) == TRUE) {
  664.                            Draw_Object(x2, y2, objptr2, FALSE, RIGHTFIELD);
  665.                            x2 = x2 - 1;
  666.                            Draw_Object(x2, y2, objptr2, TRUE, RIGHTFIELD);
  667.                         }
  668.                      } else {
  669.                      if (imsg->Code == CursorRight2) {
  670.                         if (CollisionRight(objptr2, field2, x2, y2) == TRUE) {
  671.                            Draw_Object(x2, y2, objptr2, FALSE, RIGHTFIELD);
  672.                            x2=x2+1;
  673.                            Draw_Object(x2, y2, objptr2, TRUE, RIGHTFIELD);
  674.                         }
  675.                      } else {
  676.                      if (imsg->Code == NormalSpace2) {
  677.                         if (!SpacePressed2) {
  678.                            AbortIO((struct IORequest *) TimerIO2);
  679.                            WaitIO((struct IORequest *) TimerIO2);
  680.                            SpacePressed2 = TRUE;
  681.                            oldtime2 = time2;
  682.                            time2 = pulldownticks;
  683.                         }
  684.                      } else {
  685.                      if (imsg->Code == QuickSpace2) {
  686.                         AbortIO((struct IORequest *) TimerIO2);
  687.                         WaitIO((struct IORequest *) TimerIO2);
  688.                         oldtime2 = time2;
  689.                         time2 = 0;
  690.                      } else {
  691.                         if (SpacePressed2) {
  692.                           SpacePressed2 = FALSE;
  693.                            time2 = oldtime2;
  694.                         }
  695.                         if (SpacePressed) {
  696.                           SpacePressed = FALSE;
  697.                            time = oldtime;
  698.                         }
  699.                      }
  700.                      }}}}}}}}}}}
  701.                   break;
  702.             }
  703.             ReplyMsg((struct Message *)imsg);
  704.          }
  705.       }
  706.    }
  707.  
  708.    closeall();
  709.    return(0);
  710. }
  711.  
  712.  
  713.  
  714. /*
  715. ** Fragt die Kollision nach rechts ab
  716. ** FALSE, wenn Object oder rechte Wand im Weg
  717. ** TRUE , wenn Object nach rechts verschoben werden kann
  718. */
  719. BOOL CollisionRight(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y)
  720. {
  721.    short i,j;
  722.  
  723.    for (j=3; j>=0; j--)
  724.       for (i=0; i<4; i++) {
  725.          if ((objptr->objData[i][j] > 0) && (field[y+i-1][j+x+1] != 0))
  726.             return(FALSE);
  727.       }
  728.    return(TRUE);
  729. }
  730.  
  731.  
  732.  
  733. /*
  734. ** Fragt die Kollision nach links ab
  735. ** FALSE, wenn Object oder linke Wand im Weg
  736. ** TRUE , wenn Object nach links verschoben werden kann
  737. */
  738. BOOL CollisionLeft(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y)
  739. {
  740.    short i,j;
  741.  
  742.    for (j=0; j<4; j++)
  743.       for (i=0; i<4; i++) {
  744.          if ((objptr->objData[i][j] > 0) && (field[y+i-1][j+x-1] != 0))
  745.             return(FALSE);
  746.       }
  747.    return(TRUE);
  748. }
  749.  
  750.  
  751.  
  752. /*
  753. ** Fragt die Kollision nach unten ab
  754. ** FALSE, wenn Object oder Boden im Weg
  755. ** TRUE , wenn Object nach unten verschoben werden kann
  756. */
  757. BOOL CollisionDown(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y, BOOL RightOrLeft)
  758. {
  759.    short i,j;
  760.  
  761.    for (j=0; j<4; j++)
  762.       for (i=0; i<4; i++) {
  763.          if ((objptr->objData[i][j] > 0) && (field[y+i][j+x] != 0)) {
  764.             Score = Score + Level;
  765.             SetNewMatrix(objptr, field, x, y);
  766.             CleanUp(field, RightOrLeft);
  767.             return(FALSE);
  768.          }
  769.       }
  770.    return(TRUE);
  771. }
  772.  
  773.  
  774.  
  775. void openall(void)
  776. {
  777.    if ((TimerMP = CreatePort(NULL, NULL)) == NULL)
  778.       closeout("Couldn't create messageport", RETURN_FAIL);
  779.  
  780.    if ((TimerIO = (struct timerequest *) CreateExtIO(TimerMP, sizeof(struct timerequest))) == NULL)
  781.       closeout("Couldn't create IOrequest", RETURN_FAIL);
  782.  
  783.    if ((TimerError = OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *) TimerIO, 0L)) != NULL)
  784.       closeout("Couldn't open timer.device", RETURN_FAIL);
  785.  
  786.    if (TwoPlayer) {
  787.       if ((TimerMP2 = CreatePort(NULL, NULL)) == NULL)
  788.          closeout("Couldn't create messageport", RETURN_FAIL);
  789.  
  790.       if ((TimerIO2 = (struct timerequest *) CreateExtIO(TimerMP2, sizeof(struct timerequest))) == NULL)
  791.          closeout("Couldn't create IOrequest", RETURN_FAIL);
  792.  
  793.       if ((TimerError2 = OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *) TimerIO2, 0L)) != NULL)
  794.          closeout("Couldn't open timer.device", RETURN_FAIL);
  795.    }
  796.  
  797.    if ((KeymapBase = OpenLibrary("keymap.library", 37)) == NULL)
  798.       closeout("Kickstart 2.0 required",RETURN_FAIL);
  799.  
  800.    if ((IntuitionBase = OpenLibrary("intuition.library", 37)) == NULL)
  801.       closeout("Can't open intuition",RETURN_FAIL);
  802.  
  803.    if ((font = OpenDiskFont(&helvetica13)) == NULL)
  804.       closeout("Failed to open Helvetica 13", RETURN_FAIL);
  805.  
  806.    if ((font2 = OpenDiskFont(&topaz8)) == NULL)
  807.       closeout("Failed to open Topaz 8", RETURN_FAIL);
  808.  
  809.    if ((myscreen = LockPubScreen(NULL)) == NULL)
  810.       closeout("Couldn't lock default public screen", RETURN_FAIL);
  811.  
  812.    if ((myscreen->Height) < 450)
  813.       UseLace = FALSE;
  814.  
  815.    if ((VisualInfo = GetVisualInfo(myscreen, TAG_END)) == NULL)
  816.       closeout("GetVisualInfo() failed", RETURN_FAIL);
  817. }
  818.  
  819.  
  820.  
  821. void closeall(void)
  822. {
  823.    AbortIO((struct IORequest *) TimerIO);
  824.    WaitIO((struct IORequest *) TimerIO);
  825.  
  826.    if (window)
  827.       CloseWindow(window);
  828.  
  829.    if (TetrisGList)
  830.       FreeGadgets(TetrisGList);
  831.  
  832.    if (VisualInfo)
  833.       FreeVisualInfo(VisualInfo);
  834.  
  835.    if (myscreen)
  836.       UnlockPubScreen(NULL, myscreen);
  837.  
  838.    if (IntuitionBase)
  839.       CloseLibrary(IntuitionBase);
  840.  
  841.    if (KeymapBase)
  842.       CloseLibrary(KeymapBase);
  843.  
  844.    if (!TimerError)
  845.       CloseDevice((struct IORequest *) TimerIO);
  846.  
  847.    if (TimerIO)
  848.       DeleteExtIO((struct IORequest *) TimerIO);
  849.  
  850.    if (TimerMP)
  851.       DeletePort(TimerMP);
  852.  
  853.    if (TwoPlayer) {
  854.       if (!TimerError2)
  855.          CloseDevice((struct IORequest *) TimerIO2);
  856.  
  857.       if (TimerIO2)
  858.          DeleteExtIO((struct IORequest *) TimerIO2);
  859.  
  860.       if (TimerMP2)
  861.          DeletePort(TimerMP2);
  862.    }
  863.  
  864.    exit(0);
  865. }
  866.  
  867.  
  868.  
  869. void closeout(UBYTE *errstring, LONG rc)
  870. {
  871.    struct EasyStruct myES = {
  872.       sizeof(struct EasyStruct),
  873.       0,
  874.       "WBTRIS Error",
  875.       "Error: %s\n",
  876.       "OK",
  877.    };
  878.  
  879.    if (*errstring)
  880.       EasyRequest(NULL, &myES, NULL, errstring);
  881.  
  882.     closeall();
  883.     exit(rc);
  884. }
  885.  
  886.  
  887.  
  888. BOOL Rotate_Matrixr(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y, BOOL RightOrLeft)
  889. {
  890.    short i, j;
  891.    struct obj b[1];
  892.  
  893.    b[0].objData[3][0] = objptr->objData[0][0];
  894.    b[0].objData[2][0] = objptr->objData[0][1];
  895.    b[0].objData[1][0] = objptr->objData[0][2];
  896.    b[0].objData[0][0] = objptr->objData[0][3];
  897.    b[0].objData[3][1] = objptr->objData[1][0];
  898.    b[0].objData[2][1] = objptr->objData[1][1];
  899.    b[0].objData[1][1] = objptr->objData[1][2];
  900.    b[0].objData[0][1] = objptr->objData[1][3];
  901.    b[0].objData[3][2] = objptr->objData[2][0];
  902.    b[0].objData[2][2] = objptr->objData[2][1];
  903.    b[0].objData[1][2] = objptr->objData[2][2];
  904.    b[0].objData[0][2] = objptr->objData[2][3];
  905.    b[0].objData[3][3] = objptr->objData[3][0];
  906.    b[0].objData[2][3] = objptr->objData[3][1];
  907.    b[0].objData[1][3] = objptr->objData[3][2];
  908.    b[0].objData[0][3] = objptr->objData[3][3];
  909.  
  910.    if ((CollisionRight(b, field, x-1, y) == TRUE) && (CollisionLeft(b, field, x+1, y) == TRUE) && (CollisionDown(b, field, x, y-1, RightOrLeft) == TRUE)) {
  911.       for (i=0; i<4; i++)
  912.          for (j=0; j<4; j++)
  913.             objptr->objData[i][j] = b[0].objData[i][j];
  914.       return(TRUE);
  915.    }
  916.    return(FALSE);
  917. }
  918.  
  919.  
  920.  
  921. BOOL Rotate_Matrixl(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y, BOOL RightOrLeft)
  922. {
  923.    short i, j;
  924.    struct obj b[1];
  925.  
  926.    b[0].objData[0][3] = objptr->objData[0][0];
  927.    b[0].objData[1][3] = objptr->objData[0][1];
  928.    b[0].objData[2][3] = objptr->objData[0][2];
  929.    b[0].objData[3][3] = objptr->objData[0][3];
  930.    b[0].objData[0][2] = objptr->objData[1][0];
  931.    b[0].objData[1][2] = objptr->objData[1][1];
  932.    b[0].objData[2][2] = objptr->objData[1][2];
  933.    b[0].objData[3][2] = objptr->objData[1][3];
  934.    b[0].objData[0][1] = objptr->objData[2][0];
  935.    b[0].objData[1][1] = objptr->objData[2][1];
  936.    b[0].objData[2][1] = objptr->objData[2][2];
  937.    b[0].objData[3][1] = objptr->objData[2][3];
  938.    b[0].objData[0][0] = objptr->objData[3][0];
  939.    b[0].objData[1][0] = objptr->objData[3][1];
  940.    b[0].objData[2][0] = objptr->objData[3][2];
  941.    b[0].objData[3][0] = objptr->objData[3][3];
  942.  
  943.    if ((CollisionRight(b, field, x-1, y) == TRUE) && (CollisionLeft(b, field, x+1, y) == TRUE) && (CollisionDown(b, field, x, y-1, RightOrLeft) == TRUE)) {
  944.       for (i=0; i<4; i++)
  945.          for (j=0; j<4; j++)
  946.             objptr->objData[i][j] = b[0].objData[i][j];
  947.       return(TRUE);
  948.    }
  949.    return(FALSE);
  950. }
  951.  
  952.  
  953.  
  954. void Draw_NextObject(struct obj *objptr, BOOL FieldRight)
  955. {
  956.    short i,j;
  957.  
  958.    for (i=0; i<4; i++) {
  959.       for (j=0; j<4; j++)
  960.          if (objptr->objData[i][j] > 0)
  961.             Draw_Box(j-5, i, objptr->color, TRUE, FieldRight);
  962.    }
  963. }
  964.  
  965.  
  966.  
  967. void ClearNextField(BOOL RightOrLeft)
  968. {
  969.    short i,j;
  970.  
  971.    for (i=0; i<4; i++) {
  972.       for (j=0; j<4; j++)
  973.             Draw_Box(j-5, i, 0, FALSE, RightOrLeft);
  974.    }
  975. }
  976.  
  977.  
  978.  
  979. void Draw_Object(int x, int y, struct obj *objptr, BOOL malen, BOOL RightOrLeft)
  980. {
  981.    short i,j;
  982.  
  983.    for (i=0; i<4; i++) {
  984.       for (j=0; j<4; j++)
  985.          if (objptr->objData[i][j] > 0)
  986.             Draw_Box(x+j, y+i-1, objptr->color, malen, RightOrLeft);
  987.    }
  988. }
  989.  
  990.  
  991.  
  992. void Draw_Box(int x, int y, int color, int malen, BOOL RightOrLeft)
  993. {
  994.    int TwoPLayerOffSet;
  995.  
  996.    if (RightOrLeft)
  997.       TwoPLayerOffSet = boxxsize*XSIZE + FieldsSpace;
  998.    else
  999.       TwoPLayerOffSet = 0;
  1000.  
  1001.    if (UseLace) {
  1002.       if (malen == TRUE) {
  1003.          switch(color) {
  1004.             case 1:
  1005.                DrawImage(rp, &GruenWeiss, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1006.                break;
  1007.             case 2:
  1008.                DrawImage(rp, &GruenWeissSchach, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1009.                break;
  1010.             case 3:
  1011.                DrawImage(rp, &GruenWeissSchraeg, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1012.                break;
  1013.             case 4:
  1014.                DrawImage(rp, &Schwarz, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1015.                break;
  1016.             case 5:
  1017.                DrawImage(rp, &SchwarzGruen, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1018.                break;
  1019.             case 6:
  1020.                DrawImage(rp, &SchwarzWeiss, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1021.                break;
  1022.             case 7:
  1023.                DrawImage(rp, &Gruen, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1024.                break;
  1025.          }
  1026.       } else {
  1027.          switch(color) {
  1028.             case 0:
  1029.                SetAPen(rp, 0);
  1030.                RectFill(rp, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize, MAINXOFFSET + x*boxxsize + BOXXSIZE + TwoPLayerOffSet, YOFFSET + y*boxysize + BOXYSIZE);
  1031.                break;
  1032.             case 1:
  1033.                EraseImage(rp, &GruenWeiss, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1034.                break;
  1035.             case 2:
  1036.                EraseImage(rp, &GruenWeissSchach, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1037.                break;
  1038.             case 3:
  1039.                EraseImage(rp, &GruenWeissSchraeg, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1040.                break;
  1041.             case 4:
  1042.                EraseImage(rp, &Schwarz, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1043.                break;
  1044.             case 5:
  1045.                EraseImage(rp, &SchwarzGruen, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1046.                break;
  1047.             case 6:
  1048.                EraseImage(rp, &SchwarzWeiss, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1049.                break;
  1050.             case 7:
  1051.                EraseImage(rp, &Gruen, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1052.                break;
  1053.          }
  1054.       }
  1055.    } else {
  1056.       if (malen == TRUE) {
  1057.          switch(color) {
  1058.             case 1:
  1059.                DrawImage(rp, &GruenWeissNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1060.                break;
  1061.             case 2:
  1062.                DrawImage(rp, &GruenWeissSchachNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1063.                break;
  1064.             case 3:
  1065.                DrawImage(rp, &GruenWeissSchraegNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1066.                break;
  1067.             case 4:
  1068.                DrawImage(rp, &SchwarzNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1069.                break;
  1070.             case 5:
  1071.                DrawImage(rp, &SchwarzGruenNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1072.                break;
  1073.             case 6:
  1074.                DrawImage(rp, &SchwarzWeissNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1075.                break;
  1076.             case 7:
  1077.                DrawImage(rp, &GruenNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1078.                break;
  1079.          }
  1080.       } else {
  1081.          switch(color) {
  1082.             case 0:
  1083.                SetAPen(rp, 0);
  1084.                RectFill(rp, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize, MAINXOFFSET + x*boxxsize + BOXXSIZE + TwoPLayerOffSet, YOFFSET + y*boxysize + BOXYSIZE);
  1085.                break;
  1086.             case 1:
  1087.                EraseImage(rp, &GruenWeissNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1088.                break;
  1089.             case 2:
  1090.                EraseImage(rp, &GruenWeissSchachNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1091.                break;
  1092.             case 3:
  1093.                EraseImage(rp, &GruenWeissSchraegNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1094.                break;
  1095.             case 4:
  1096.                EraseImage(rp, &SchwarzNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1097.                break;
  1098.             case 5:
  1099.                EraseImage(rp, &SchwarzGruenNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1100.                break;
  1101.             case 6:
  1102.                EraseImage(rp, &SchwarzWeissNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1103.                break;
  1104.             case 7:
  1105.                EraseImage(rp, &GruenNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOFFSET + y*boxysize);
  1106.                break;
  1107.          }
  1108.       }
  1109.    }
  1110. }
  1111.  
  1112.  
  1113.  
  1114. struct obj *RandomObject(BOOL RightOrLeft)
  1115. {
  1116.    static ULONG RandomResult = 0L; /* So the last random-number is still stored ! */
  1117.    ULONG Sec,Mic;
  1118.  
  1119.    CurrentTime((LONG *)&Sec,(LONG *)&Mic);
  1120.  
  1121.    RandomResult *= Sec;
  1122.    RandomResult += Mic;
  1123.  
  1124.    while (RandomResult > 32767L) RandomResult = RandomResult>>1;
  1125.  
  1126.    RandomResult = RandomResult % 7;
  1127.  
  1128.    UpdateStatistic(RandomResult);
  1129.  
  1130.    if (RightOrLeft == LEFTFIELD) {
  1131.       switch(RandomResult) {
  1132.          case 0:
  1133.             return(&objects[1]);
  1134.             break;
  1135.          case 1:
  1136.             return(&objects[2]);
  1137.             break;
  1138.          case 2:
  1139.             return(&objects[3]);
  1140.             break;
  1141.          case 3:
  1142.             return(&objects[4]);
  1143.             break;
  1144.          case 4:
  1145.             return(&objects[5]);
  1146.             break;
  1147.          case 5:
  1148.             return(&objects[6]);
  1149.             break;
  1150.          default:
  1151.             return(&objects[7]);
  1152.       }
  1153.    } else {
  1154.       switch(RandomResult) {
  1155.          case 0:
  1156.             return(&objects2[1]);
  1157.             break;
  1158.          case 1:
  1159.             return(&objects2[2]);
  1160.             break;
  1161.          case 2:
  1162.             return(&objects2[3]);
  1163.             break;
  1164.          case 3:
  1165.             return(&objects2[4]);
  1166.             break;
  1167.          case 4:
  1168.             return(&objects2[5]);
  1169.             break;
  1170.          case 5:
  1171.             return(&objects2[6]);
  1172.             break;
  1173.          default:
  1174.             return(&objects2[7]);
  1175.       }
  1176.    }
  1177. }
  1178.  
  1179.  
  1180.  
  1181. void DrawWindow(void)
  1182. {
  1183.    /* Mainfield */
  1184.    if (UseLace)
  1185.       DrawBevelBox(rp, MAINXOFFSET+14, YOFFSET-2, (XSIZE+1)*boxxsize-10, YSIZE*boxysize+5, GT_VisualInfo, VisualInfo);
  1186.    else
  1187.       DrawBevelBox(rp, MAINXOFFSET+13, YOFFSET-2, (XSIZE+1)*boxxsize-10, YSIZE*boxysize+5, GT_VisualInfo, VisualInfo);
  1188.  
  1189.    /* Next Object Field */
  1190.    DrawBevelBox(rp, NEXTXOFFSET+14, YOFFSET-2, 5*boxxsize-10, 4*boxysize+4, GTBB_Recessed, TRUE, GT_VisualInfo, VisualInfo);
  1191.  
  1192.    /* Logo */
  1193.    if (UseLace)
  1194.       DrawImage(rp, &logo, LGXOS + 20, LGYOS + 320);
  1195.    else
  1196.       DrawImage(rp, &logo, LGXOS, LGYOS + 3);
  1197.  
  1198.  
  1199.    /*
  1200.    ** Only for 2 player mode
  1201.    */
  1202.    if (TwoPlayer) {
  1203.       /* Mainfield */
  1204.       if (UseLace)
  1205.          DrawBevelBox(rp, XSIZE*boxxsize + MAINXOFFSET+14 + FieldsSpace, YOFFSET-2, (XSIZE+1)*boxxsize-10, YSIZE*boxysize+5, GT_VisualInfo, VisualInfo);
  1206.       else
  1207.          DrawBevelBox(rp, XSIZE*boxxsize + MAINXOFFSET+13 + FieldsSpace, YOFFSET-2, (XSIZE+1)*boxxsize-10, YSIZE*boxysize+5, GT_VisualInfo, VisualInfo);
  1208.  
  1209.       /* Next Object Field */
  1210.       DrawBevelBox(rp, XSIZE*boxxsize + NEXTXOFFSET+14 + FieldsSpace, YOFFSET-2, 5*boxxsize-10, 4*boxysize+4, GTBB_Recessed, TRUE, GT_VisualInfo, VisualInfo);
  1211.    }
  1212. }
  1213.  
  1214.  
  1215.  
  1216. void SetNewMatrix(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y)
  1217. {
  1218.    short line, column;
  1219.  
  1220.    for (line=0; line<4; line++)
  1221.       for (column=0; column<4; column++) {
  1222.          if (objptr->objData[line][column] == 1)
  1223.             field[y+line-1][x+column] = objptr->color;
  1224.       }
  1225. }
  1226.  
  1227.  
  1228.  
  1229. void CleanUp(int ThisField[YSIZE+1][XSIZE+2], BOOL RightOrLeft)
  1230. {
  1231.    int i, j, line, column;
  1232.    BOOL Update = FALSE;
  1233.    BOOL KeineNull = TRUE;
  1234.    int LinesToRemove = 0;
  1235.  
  1236.    Lines = 0;
  1237.    for (line=1; line < YSIZE; line++) {
  1238.       for (column=1; column < XSIZE+1; column++)
  1239.          if (ThisField[line][column] == 0)
  1240.             KeineNull = FALSE;
  1241.  
  1242.       if (KeineNull == TRUE)
  1243.       {
  1244.          Lines++;
  1245.          LinesToRemove++;
  1246.          Update = TRUE;
  1247.          for (j=line; j>0; j--)
  1248.             for (i=1; i<XSIZE+1; i++)
  1249.                ThisField[j][i] = ThisField[j-1][i];
  1250.       }
  1251.       KeineNull = TRUE;
  1252.    }
  1253.  
  1254.    if (Update == TRUE) {
  1255.       if (TwoPlayer ) {
  1256.          if (LinesToRemove > 0) {
  1257.             if (RightOrLeft == RIGHTFIELD)
  1258.                PutRows(field, LEFTFIELD, LinesToRemove);
  1259.             else
  1260.                PutRows(field2, RIGHTFIELD, LinesToRemove);
  1261.          }
  1262.       }
  1263.       ReDrawField(ThisField, RightOrLeft);
  1264.    }
  1265.  
  1266.    LineCounter = LineCounter + Lines;
  1267.    Level = LineCounter / 10 + LevelOffset;
  1268.    if (Level >= 20)
  1269.       oldtime = 0;
  1270.    else
  1271.       oldtime = DEFAULTTICKS - Level*2;
  1272.    time = oldtime;
  1273.  
  1274.    if (TwoPlayer) {
  1275.       if (Level >= 20)
  1276.          oldtime2 = 0;
  1277.       else
  1278.          oldtime2 = DEFAULTTICKS - Level*2;
  1279.       time2 = oldtime2;
  1280.    }
  1281.  
  1282.    if (Level == 0)
  1283.       Score = Score + 5*Lines*Lines*(Level+1);
  1284.    else
  1285.       Score = Score + 10*Lines*Lines*Level;
  1286.  
  1287.    if (Score > Highscore)
  1288.       Highscore = Score;
  1289.  
  1290.    GT_SetGadgetAttrs(TetrisGadgets[GD_HighscoreGadget], window, NULL,
  1291.                      GTNM_Number, (ULONG)Highscore,
  1292.                      TAG_END);
  1293.    GT_SetGadgetAttrs(TetrisGadgets[GD_ScoreGadget], window, NULL,
  1294.                      GTNM_Number, (ULONG)Score,
  1295.                      TAG_END);
  1296.    GT_SetGadgetAttrs(TetrisGadgets[GD_LevelGadget], window, NULL,
  1297.                      GTNM_Number, (ULONG)Level,
  1298.                      TAG_END);
  1299.    GT_SetGadgetAttrs(TetrisGadgets[GD_LineGadget], window, NULL,
  1300.                      GTNM_Number, (ULONG)LineCounter,
  1301.                      TAG_END);
  1302. }
  1303.  
  1304.  
  1305.  
  1306. /*
  1307. ** Ist der obere Rand erreicht, dann ist das Spiel zu Ende
  1308. ** TRUE,  wenn oberer Rand erreicht
  1309. ** FALSE, wenn nicht
  1310. */
  1311. BOOL GameOver(int field[YSIZE+1][XSIZE+2],BOOL lockname)
  1312. {
  1313.    int column;
  1314.  
  1315.    for (column=0; column<=XSIZE; column++) {
  1316.       if (field[1][column] > 0) {
  1317.          if (Score > Highscore)
  1318.          Highscore = Score;
  1319.  
  1320.          if ((lockname == FALSE) || (strlen(Name) == 0))
  1321.             AskForName();
  1322.          HiscoreList(Name, Level, Score, LineCounter, window->LeftEdge, window->TopEdge, SAVEHISCORE);
  1323.  
  1324.          if ((AskContinue()) == TRUE) {
  1325.              Score = 0;
  1326.              LineCounter = 0;
  1327.              Level = LevelOffset;
  1328.              NewGame(field, TRUE, FALSE);
  1329.          }
  1330.          else
  1331.             return(TRUE);
  1332.       }
  1333.    }
  1334.    return(FALSE);
  1335. }
  1336.  
  1337.  
  1338.  
  1339. /*
  1340. ** Hier wird den Objekten die Form und die Farbe gegeben
  1341. */
  1342. void InitObjects(void)
  1343. {
  1344.   objects[0].objData[0][0] = 0; objects[0].objData[0][1] = 0; objects[0].objData[0][2] = 0; objects[0].objData[0][3] = 0;
  1345.   objects[0].objData[1][0] = 0; objects[0].objData[1][1] = 0; objects[0].objData[1][2] = 0; objects[0].objData[1][3] = 0;
  1346.   objects[0].objData[2][0] = 0; objects[0].objData[2][1] = 0; objects[0].objData[2][2] = 0; objects[0].objData[2][3] = 0;
  1347.   objects[0].objData[3][0] = 0; objects[0].objData[3][1] = 0; objects[0].objData[3][2] = 0; objects[0].objData[3][3] = 0;
  1348.   objects[0].color = 0;
  1349.  
  1350.   objects[1].objData[0][0] = 0; objects[1].objData[0][1] = 0; objects[1].objData[0][2] = 0; objects[1].objData[0][3] = 0;
  1351.   objects[1].objData[1][0] = 0; objects[1].objData[1][1] = 1; objects[1].objData[1][2] = 1; objects[1].objData[1][3] = 0;
  1352.   objects[1].objData[2][0] = 0; objects[1].objData[2][1] = 1; objects[1].objData[2][2] = 1; objects[1].objData[2][3] = 0;
  1353.   objects[1].objData[3][0] = 0; objects[1].objData[3][1] = 0; objects[1].objData[3][2] = 0; objects[1].objData[3][3] = 0;
  1354.   objects[1].color = 1;
  1355.  
  1356.   objects[2].objData[0][0] = 0; objects[2].objData[0][1] = 1; objects[2].objData[0][2] = 0; objects[2].objData[0][3] = 0;
  1357.   objects[2].objData[1][0] = 0; objects[2].objData[1][1] = 1; objects[2].objData[1][2] = 0; objects[2].objData[1][3] = 0;
  1358.   objects[2].objData[2][0] = 0; objects[2].objData[2][1] = 1; objects[2].objData[2][2] = 0; objects[2].objData[2][3] = 0;
  1359.   objects[2].objData[3][0] = 0; objects[2].objData[3][1] = 1; objects[2].objData[3][2] = 0; objects[2].objData[3][3] = 0;
  1360.   objects[2].color = 2;
  1361.  
  1362.   objects[3].objData[0][0] = 0; objects[3].objData[0][1] = 0; objects[3].objData[0][2] = 0; objects[3].objData[0][3] = 0;
  1363.   objects[3].objData[1][0] = 0; objects[3].objData[1][1] = 0; objects[3].objData[1][2] = 1; objects[3].objData[1][3] = 0;
  1364.   objects[3].objData[2][0] = 0; objects[3].objData[2][1] = 1; objects[3].objData[2][2] = 1; objects[3].objData[2][3] = 0;
  1365.   objects[3].objData[3][0] = 0; objects[3].objData[3][1] = 0; objects[3].objData[3][2] = 1; objects[3].objData[3][3] = 0;
  1366.   objects[3].color = 3;
  1367.  
  1368.   objects[4].objData[0][0] = 0; objects[4].objData[0][1] = 0; objects[4].objData[0][2] = 0; objects[4].objData[0][3] = 0;
  1369.   objects[4].objData[1][0] = 1; objects[4].objData[1][1] = 1; objects[4].objData[1][2] = 1; objects[4].objData[1][3] = 0;
  1370.   objects[4].objData[2][0] = 0; objects[4].objData[2][1] = 0; objects[4].objData[2][2] = 1; objects[4].objData[2][3] = 0;
  1371.   objects[4].objData[3][0] = 0; objects[4].objData[3][1] = 0; objects[4].objData[3][2] = 0; objects[4].objData[3][3] = 0;
  1372.   objects[4].color = 4;
  1373.  
  1374.   objects[5].objData[0][0] = 0; objects[5].objData[0][1] = 0; objects[5].objData[0][2] = 0; objects[5].objData[0][3] = 0;
  1375.   objects[5].objData[1][0] = 0; objects[5].objData[1][1] = 0; objects[5].objData[1][2] = 1; objects[5].objData[1][3] = 0;
  1376.   objects[5].objData[2][0] = 1; objects[5].objData[2][1] = 1; objects[5].objData[2][2] = 1; objects[5].objData[2][3] = 0;
  1377.   objects[5].objData[3][0] = 0; objects[5].objData[3][1] = 0; objects[5].objData[3][2] = 0; objects[5].objData[3][3] = 0;
  1378.   objects[5].color = 5;
  1379.  
  1380.   objects[6].objData[0][0] = 0; objects[6].objData[0][1] = 1; objects[6].objData[0][2] = 0; objects[6].objData[0][3] = 0;
  1381.   objects[6].objData[1][0] = 0; objects[6].objData[1][1] = 1; objects[6].objData[1][2] = 1; objects[6].objData[1][3] = 0;
  1382.   objects[6].objData[2][0] = 0; objects[6].objData[2][1] = 0; objects[6].objData[2][2] = 1; objects[6].objData[2][3] = 0;
  1383.   objects[6].objData[3][0] = 0; objects[6].objData[3][1] = 0; objects[6].objData[3][2] = 0; objects[6].objData[3][3] = 0;
  1384.   objects[6].color = 6;
  1385.  
  1386.   objects[7].objData[0][0] = 0; objects[7].objData[0][1] = 0; objects[7].objData[0][2] = 0; objects[7].objData[0][3] = 0;
  1387.   objects[7].objData[1][0] = 0; objects[7].objData[1][1] = 0; objects[7].objData[1][2] = 1; objects[7].objData[1][3] = 0;
  1388.   objects[7].objData[2][0] = 0; objects[7].objData[2][1] = 1; objects[7].objData[2][2] = 1; objects[7].objData[2][3] = 0;
  1389.   objects[7].objData[3][0] = 0; objects[7].objData[3][1] = 1; objects[7].objData[3][2] = 0; objects[7].objData[3][3] = 0;
  1390.   objects[7].color = 7;
  1391.  
  1392.  
  1393.   objects2[0].objData[0][0] = 0; objects2[0].objData[0][1] = 0; objects2[0].objData[0][2] = 0; objects2[0].objData[0][3] = 0;
  1394.   objects2[0].objData[1][0] = 0; objects2[0].objData[1][1] = 0; objects2[0].objData[1][2] = 0; objects2[0].objData[1][3] = 0;
  1395.   objects2[0].objData[2][0] = 0; objects2[0].objData[2][1] = 0; objects2[0].objData[2][2] = 0; objects2[0].objData[2][3] = 0;
  1396.   objects2[0].objData[3][0] = 0; objects2[0].objData[3][1] = 0; objects2[0].objData[3][2] = 0; objects2[0].objData[3][3] = 0;
  1397.   objects2[0].color = 0;
  1398.  
  1399.   objects2[1].objData[0][0] = 0; objects2[1].objData[0][1] = 0; objects2[1].objData[0][2] = 0; objects2[1].objData[0][3] = 0;
  1400.   objects2[1].objData[1][0] = 0; objects2[1].objData[1][1] = 1; objects2[1].objData[1][2] = 1; objects2[1].objData[1][3] = 0;
  1401.   objects2[1].objData[2][0] = 0; objects2[1].objData[2][1] = 1; objects2[1].objData[2][2] = 1; objects2[1].objData[2][3] = 0;
  1402.   objects2[1].objData[3][0] = 0; objects2[1].objData[3][1] = 0; objects2[1].objData[3][2] = 0; objects2[1].objData[3][3] = 0;
  1403.   objects2[1].color = 1;
  1404.  
  1405.   objects2[2].objData[0][0] = 0; objects2[2].objData[0][1] = 1; objects2[2].objData[0][2] = 0; objects2[2].objData[0][3] = 0;
  1406.   objects2[2].objData[1][0] = 0; objects2[2].objData[1][1] = 1; objects2[2].objData[1][2] = 0; objects2[2].objData[1][3] = 0;
  1407.   objects2[2].objData[2][0] = 0; objects2[2].objData[2][1] = 1; objects2[2].objData[2][2] = 0; objects2[2].objData[2][3] = 0;
  1408.   objects2[2].objData[3][0] = 0; objects2[2].objData[3][1] = 1; objects2[2].objData[3][2] = 0; objects2[2].objData[3][3] = 0;
  1409.   objects2[2].color = 2;
  1410.  
  1411.   objects2[3].objData[0][0] = 0; objects2[3].objData[0][1] = 0; objects2[3].objData[0][2] = 0; objects2[3].objData[0][3] = 0;
  1412.   objects2[3].objData[1][0] = 0; objects2[3].objData[1][1] = 0; objects2[3].objData[1][2] = 1; objects2[3].objData[1][3] = 0;
  1413.   objects2[3].objData[2][0] = 0; objects2[3].objData[2][1] = 1; objects2[3].objData[2][2] = 1; objects2[3].objData[2][3] = 0;
  1414.   objects2[3].objData[3][0] = 0; objects2[3].objData[3][1] = 0; objects2[3].objData[3][2] = 1; objects2[3].objData[3][3] = 0;
  1415.   objects2[3].color = 3;
  1416.  
  1417.   objects2[4].objData[0][0] = 0; objects2[4].objData[0][1] = 0; objects2[4].objData[0][2] = 0; objects2[4].objData[0][3] = 0;
  1418.   objects2[4].objData[1][0] = 1; objects2[4].objData[1][1] = 1; objects2[4].objData[1][2] = 1; objects2[4].objData[1][3] = 0;
  1419.   objects2[4].objData[2][0] = 0; objects2[4].objData[2][1] = 0; objects2[4].objData[2][2] = 1; objects2[4].objData[2][3] = 0;
  1420.   objects2[4].objData[3][0] = 0; objects2[4].objData[3][1] = 0; objects2[4].objData[3][2] = 0; objects2[4].objData[3][3] = 0;
  1421.   objects2[4].color = 4;
  1422.  
  1423.   objects2[5].objData[0][0] = 0; objects2[5].objData[0][1] = 0; objects2[5].objData[0][2] = 0; objects2[5].objData[0][3] = 0;
  1424.   objects2[5].objData[1][0] = 0; objects2[5].objData[1][1] = 0; objects2[5].objData[1][2] = 1; objects2[5].objData[1][3] = 0;
  1425.   objects2[5].objData[2][0] = 1; objects2[5].objData[2][1] = 1; objects2[5].objData[2][2] = 1; objects2[5].objData[2][3] = 0;
  1426.   objects2[5].objData[3][0] = 0; objects2[5].objData[3][1] = 0; objects2[5].objData[3][2] = 0; objects2[5].objData[3][3] = 0;
  1427.   objects2[5].color = 5;
  1428.  
  1429.   objects2[6].objData[0][0] = 0; objects2[6].objData[0][1] = 1; objects2[6].objData[0][2] = 0; objects2[6].objData[0][3] = 0;
  1430.   objects2[6].objData[1][0] = 0; objects2[6].objData[1][1] = 1; objects2[6].objData[1][2] = 1; objects2[6].objData[1][3] = 0;
  1431.   objects2[6].objData[2][0] = 0; objects2[6].objData[2][1] = 0; objects2[6].objData[2][2] = 1; objects2[6].objData[2][3] = 0;
  1432.   objects2[6].objData[3][0] = 0; objects2[6].objData[3][1] = 0; objects2[6].objData[3][2] = 0; objects2[6].objData[3][3] = 0;
  1433.   objects2[6].color = 6;
  1434.  
  1435.   objects2[7].objData[0][0] = 0; objects2[7].objData[0][1] = 0; objects2[7].objData[0][2] = 0; objects2[7].objData[0][3] = 0;
  1436.   objects2[7].objData[1][0] = 0; objects2[7].objData[1][1] = 0; objects2[7].objData[1][2] = 1; objects2[7].objData[1][3] = 0;
  1437.   objects2[7].objData[2][0] = 0; objects2[7].objData[2][1] = 1; objects2[7].objData[2][2] = 1; objects2[7].objData[2][3] = 0;
  1438.   objects2[7].objData[3][0] = 0; objects2[7].objData[3][1] = 1; objects2[7].objData[3][2] = 0; objects2[7].objData[3][3] = 0;
  1439.   objects2[7].color = 7;
  1440. }
  1441.  
  1442.  
  1443. /*
  1444. ** Das Programm kann angehalten werden
  1445. */
  1446. BOOL Pause(void)
  1447. {
  1448.    BOOL                 Done = FALSE;
  1449.    struct IntuiMessage *imsg = NULL;
  1450.    struct Gadget       *gad = NULL;
  1451.    int                  line,column;
  1452.  
  1453.    GT_SetGadgetAttrs(TetrisGadgets[GD_PauseGadget], window, NULL,
  1454.                      GTCY_Labels, &CYCLELabels[1], TAG_END);
  1455.    GT_SetGadgetAttrs(TetrisGadgets[GD_NewGadget], window, NULL,
  1456.                      GA_Disabled, TRUE, TAG_END);
  1457.    GT_SetGadgetAttrs(TetrisGadgets[GD_ShowScoreGadget], window, NULL,
  1458.                      GA_Disabled, FALSE, TAG_END);
  1459.    GT_SetGadgetAttrs(TetrisGadgets[GD_OptGadget], window, NULL,
  1460.                      GA_Disabled, TRUE, TAG_END);
  1461.  
  1462.    HideField();
  1463.  
  1464.    while(!Done)
  1465.    {
  1466.       Wait(1L << window->UserPort->mp_SigBit);
  1467.  
  1468.       while (imsg = (struct IntuiMessage *)GetMsg(window->UserPort)) {
  1469.          switch(imsg->Class) {
  1470.             case IDCMP_GADGETUP:
  1471.                gad = (struct Gadget *)imsg->IAddress;
  1472.                switch(gad->GadgetID) {
  1473.                   case GD_PauseGadget:
  1474.                      GT_SetGadgetAttrs(TetrisGadgets[GD_PauseGadget], window, NULL,
  1475.                                        GA_Disabled, FALSE, TAG_END);
  1476.                      GT_SetGadgetAttrs(TetrisGadgets[GD_NewGadget], window, NULL,
  1477.                                        GA_Disabled, FALSE, TAG_END);
  1478.                      GT_SetGadgetAttrs(TetrisGadgets[GD_ShowScoreGadget], window, NULL,
  1479.                                        GA_Disabled, FALSE, TAG_END);
  1480.                      GT_SetGadgetAttrs(TetrisGadgets[GD_OptGadget], window, NULL,
  1481.                                        GA_Disabled, FALSE, TAG_END);
  1482.                      GT_SetGadgetAttrs(TetrisGadgets[GD_PauseGadget], window, NULL,
  1483.                                        GTCY_Labels, &CYCLELabels[0], TAG_END);
  1484.                      Done = TRUE;
  1485.                      break;
  1486.                   case GD_StatGadget:
  1487.                      statistic(window->LeftEdge, window->TopEdge, obj1, obj2, obj3, obj4, obj5, obj6, obj7);
  1488.                      break;
  1489.                }
  1490.                break;
  1491.  
  1492.             case IDCMP_REFRESHWINDOW:
  1493.                GT_BeginRefresh(window);
  1494.                GT_EndRefresh(window, TRUE);
  1495.                break;
  1496.  
  1497.             case IDCMP_CLOSEWINDOW:
  1498.                QuitGame();
  1499.                break;
  1500.          }
  1501.          ReplyMsg((struct Message *)imsg);
  1502.       }
  1503.    }
  1504.    if (UseLace)
  1505.       EraseImage(rp, &Pausebrush, 190,150);
  1506.    else
  1507.       EraseImage(rp, &Pausebrush, 310,85);
  1508.  
  1509.    if (TwoPlayer) {
  1510.       if (UseLace)
  1511.          EraseImage(rp, &Pausebrush, 190 + XSIZE*boxxsize + FieldsSpace,150);
  1512.       else
  1513.          EraseImage(rp, &Pausebrush, 310 + XSIZE*boxxsize + FieldsSpace,85);
  1514.    }
  1515.  
  1516.    ReDrawField(field, LEFTFIELD);
  1517.    ReDrawField(field2, RIGHTFIELD);
  1518.  
  1519.    if (TwoPlayer) {
  1520.       for (line=1; line < YSIZE; line++) {
  1521.          for (column=1; column < XSIZE+1; column++) {
  1522.             switch(field2[line][column]) {
  1523.                case 0:
  1524.                   Draw_Box(column, line, 0, FALSE, RIGHTFIELD);
  1525.                   break;
  1526.                case 1:
  1527.                   Draw_Box(column, line, 1, TRUE, RIGHTFIELD);
  1528.                   break;
  1529.                case 2:
  1530.                   Draw_Box(column, line, 2, TRUE, RIGHTFIELD);
  1531.                   break;
  1532.                case 3:
  1533.                   Draw_Box(column, line, 3, TRUE, RIGHTFIELD);
  1534.                   break;
  1535.                case 4:
  1536.                   Draw_Box(column, line, 4, TRUE, RIGHTFIELD);
  1537.                   break;
  1538.                case 5:
  1539.                   Draw_Box(column, line, 5, TRUE, RIGHTFIELD);
  1540.                   break;
  1541.                case 6:
  1542.                   Draw_Box(column, line, 6, TRUE, RIGHTFIELD);
  1543.                   break;
  1544.                case 7:
  1545.                   Draw_Box(column, line, 7, TRUE, RIGHTFIELD);
  1546.                   break;
  1547.             }
  1548.          }
  1549.       }
  1550.    }
  1551.    return(FALSE);
  1552. }
  1553.  
  1554.  
  1555.  
  1556. /*
  1557. ** Ein neues Spiel starten
  1558. */
  1559. void NewGame(int ThisField[YSIZE+1][XSIZE+2], BOOL vongameover, BOOL vonoptions)
  1560. {
  1561.    int line, column;
  1562.  
  1563.    AbortIO((struct IORequest *) TimerIO);
  1564.    WaitIO((struct IORequest *) TimerIO);
  1565.  
  1566.    Level = LevelOffset;
  1567.    time = oldtime = DEFAULTTICKS - 2*LevelOffset;
  1568.  
  1569.    /* Feld loeschen */
  1570.    for (line=0; line < YSIZE; line++)
  1571.       for (column=1; column<=XSIZE; column++) {
  1572.          field[line][column] = 0;
  1573.          Draw_Box(column, line, 0, FALSE, LEFTFIELD);
  1574.       }
  1575.  
  1576.    ClearNextField(LEFTFIELD);
  1577.  
  1578.    nextptr = RandomObject(LEFTFIELD);
  1579.    objptr = RandomObject(LEFTFIELD);
  1580.    if (nextteil == TRUE)
  1581.       Draw_NextObject(nextptr, FALSE);
  1582.  
  1583.    x = XSIZE/2-1;
  1584.    y = 0;
  1585.    if (InFirstLine(objptr) == TRUE)
  1586.       y = 1;
  1587.  
  1588.    if (TwoPlayer) {
  1589.       time2 = oldtime2 = DEFAULTTICKS - 2*LevelOffset;
  1590.       /* Feld loeschen */
  1591.       for (line=0; line < YSIZE; line++)
  1592.          for (column=1; column<=XSIZE; column++) {
  1593.             field2[line][column] = 0;
  1594.             Draw_Box(column, line, 0, FALSE, RIGHTFIELD);
  1595.          }
  1596.  
  1597.       ClearNextField(RIGHTFIELD);
  1598.  
  1599.       nextptr2 = RandomObject(RIGHTFIELD);
  1600.       objptr2 = RandomObject(RIGHTFIELD);
  1601.       if (nextteil == TRUE)
  1602.          Draw_NextObject(nextptr2, TRUE);
  1603.  
  1604.       x2 = XSIZE/2-1;
  1605.       y2 = 0;
  1606.       if (InFirstLine(objptr2) == TRUE)
  1607.          y2 = 1;
  1608.    }
  1609.  
  1610.    vongameover = FALSE;
  1611.    vonoptions = FALSE;
  1612.  
  1613.    LineCounter = 0;
  1614.  
  1615.    if (Score > Highscore)
  1616.       GT_SetGadgetAttrs(TetrisGadgets[GD_HighscoreGadget], window, NULL, GTNM_Number, (ULONG)Score, TAG_END);
  1617.    else
  1618.       GT_SetGadgetAttrs(TetrisGadgets[GD_HighscoreGadget], window, NULL, GTNM_Number, (ULONG)Highscore, TAG_END);
  1619.  
  1620.    Score = 0;
  1621.  
  1622.    GT_SetGadgetAttrs(TetrisGadgets[GD_ScoreGadget], window, NULL,
  1623.                      GTNM_Number, (ULONG)Score, TAG_END);
  1624.    GT_SetGadgetAttrs(TetrisGadgets[GD_LevelGadget], window, NULL,
  1625.                      GTNM_Number, (ULONG)Level, TAG_END);
  1626.    GT_SetGadgetAttrs(TetrisGadgets[GD_LineGadget], window, NULL,
  1627.                      GTNM_Number, (ULONG)LineCounter, TAG_END);
  1628. }
  1629.  
  1630.  
  1631.  
  1632. void QuitGame(void)
  1633. {
  1634.    if (Score > Highscore) {
  1635.       Highscore = Score;
  1636.       HiscoreList(Name, Level, Score, LineCounter, window->LeftEdge, window->TopEdge, SAVEHISCORE);
  1637.    }
  1638.    closeall();
  1639. }
  1640.  
  1641.  
  1642.  
  1643. BOOL InFirstLine(struct obj *objptr)
  1644. {
  1645.    int column;
  1646.  
  1647.    for (column=0; column<4; column++)
  1648.       if (objptr->objData[0][column] == 1)
  1649.          return(TRUE);
  1650.    return(FALSE);
  1651. }
  1652.  
  1653.  
  1654.  
  1655. int Loadhiscore(void)
  1656. {
  1657.    char   score[10];
  1658.    int    zaehler = 0, hiscore = 0, c;
  1659.    FILE  *fp = NULL;
  1660.    char  *ptr = NULL;
  1661.    char   FName[80];
  1662.  
  1663.    if (getenv("WBTRIS"))
  1664.       strcpy(FName, getenv("WBTRIS"));
  1665.    else
  1666.       strcpy(FName, FILENAME);
  1667.  
  1668.    ptr = &score[0];
  1669.  
  1670.    if ((fp = fopen(FName, "r")) == NULL)
  1671.       return(0);
  1672.    else {
  1673.       while (((c=getc(fp)) != EOF) && (zaehler != 2))
  1674.          if (c == '/') zaehler++;
  1675.  
  1676.       if (c != EOF) {
  1677.          while (c != '/') {
  1678.             *ptr = c;
  1679.             ptr++;
  1680.             c = getc(fp);
  1681.          }
  1682.          *ptr = '\0';
  1683.          hiscore = atoi(score);
  1684.       }
  1685.  
  1686.       fclose(fp);
  1687.       return(hiscore);
  1688.    }
  1689. }
  1690.  
  1691.  
  1692.  
  1693. BOOL AskContinue(void)
  1694. {
  1695.    struct EasyStruct myES = {
  1696.        sizeof(struct EasyStruct),
  1697.        0,
  1698.        "Continue",
  1699.        "Game over\n\nDo you want to play again ?",
  1700.        "YEA|No thanks",
  1701.    };
  1702.    LONG answer;
  1703.  
  1704.    answer = EasyRequest(NULL, &myES, NULL, "(Variable)");
  1705.  
  1706.    if (answer == 1)
  1707.       return(TRUE);
  1708.    else
  1709.       closeall();
  1710. }
  1711.  
  1712.  
  1713.  
  1714. void WaitForActivateWindow(void)
  1715. {
  1716.    BOOL                 Done = FALSE;
  1717.    struct IntuiMessage *imsg = NULL;
  1718.  
  1719.    AbortIO((struct IORequest *) TimerIO);
  1720.    WaitIO((struct IORequest *) TimerIO);
  1721.  
  1722.    HideField();
  1723.  
  1724.    while(!Done)
  1725.    {
  1726.       Wait(1L << window->UserPort->mp_SigBit);
  1727.  
  1728.       while (imsg = (struct IntuiMessage *)GetMsg(window->UserPort)) {
  1729.          switch(imsg->Class) {
  1730.             case IDCMP_ACTIVEWINDOW:
  1731.                Done = TRUE;
  1732.                break;
  1733.  
  1734.             case IDCMP_REFRESHWINDOW:
  1735.                GT_BeginRefresh(window);
  1736.                GT_EndRefresh(window, TRUE);
  1737.                break;
  1738.  
  1739.             case IDCMP_CLOSEWINDOW:
  1740.                QuitGame();
  1741.                break;
  1742.          }
  1743.          ReplyMsg((struct Message *)imsg);
  1744.       }
  1745.    }
  1746.  
  1747.    if (UseLace)
  1748.       EraseImage(rp, &Pausebrush, 190,150);
  1749.    else
  1750.       EraseImage(rp, &Pausebrush, 310,85);
  1751.  
  1752.    ReDrawField(field, LEFTFIELD);
  1753.    ReDrawField(field2, RIGHTFIELD);
  1754. }
  1755.  
  1756.  
  1757.  
  1758. void UpdateStatistic(int objnumber)
  1759. {
  1760.    switch(objnumber) {
  1761.       case 0:
  1762.          obj1++;
  1763.          break;
  1764.       case 1:
  1765.          obj2++;
  1766.          break;
  1767.       case 2:
  1768.          obj3++;
  1769.          break;
  1770.       case 3:
  1771.          obj4++;
  1772.          break;
  1773.       case 4:
  1774.          obj5++;
  1775.          break;
  1776.       case 5:
  1777.          obj6++;
  1778.          break;
  1779.       case 6:
  1780.          obj7++;
  1781.          break;
  1782.    }
  1783. }
  1784.  
  1785.  
  1786.  
  1787. /*
  1788. ** Put rows onto the opponent's fieldbottom (only for 2-player-mode)
  1789. */
  1790. void PutRows(int field[YSIZE+1][XSIZE+2], BOOL RightOrLeft, int NumberOfRows)
  1791. {
  1792.    int i, j;
  1793.    short line, column;
  1794.    BOOL FoundNull = FALSE;
  1795.    int NewRow[XSIZE+2];
  1796.    short Farbe;
  1797.  
  1798.    /* build new row */
  1799.    Farbe = 1 + rand() % 7;
  1800.    for (i = 0; i < XSIZE+2; i++)
  1801.       NewRow[i] = Farbe;
  1802.    NewRow[0]       = -1;
  1803.    NewRow[XSIZE+1] = -1;
  1804.    NewRow[1 + rand() % XSIZE] = 0;
  1805.  
  1806.    /* Put rows onto the opponent's field */
  1807.    for (j = 0; j < NumberOfRows; j++) {
  1808.  
  1809.       /* move field one row up */
  1810.       for (line = 0; line < YSIZE-1; line++)
  1811.          for (column = 1; column < XSIZE + 1; column++)
  1812.             field[line][column] = field[line+1][column];
  1813.  
  1814.       /* insert new row */
  1815.       for (i=0; i<XSIZE+2; i++)
  1816.          field[YSIZE-1][i] = NewRow[i];
  1817.  
  1818.       /* Abfrage auf Spielende */
  1819.       /*GameOver(field, lockname);*/
  1820.  
  1821.       /* Redraw the field */
  1822.       ReDrawField(field, RightOrLeft);
  1823.       if (RightOrLeft == RIGHTFIELD)
  1824.          Draw_Object(x2, y2, objptr2, TRUE, RIGHTFIELD);
  1825.       else
  1826.          Draw_Object(x, y, objptr, TRUE, LEFTFIELD);
  1827.    }
  1828. }
  1829.  
  1830.  
  1831.  
  1832. /*
  1833. ** executes a refresh of the playfield(s)
  1834. */
  1835. void ReDrawField(int field[YSIZE+1][XSIZE+2], BOOL RightOrLeft)
  1836. {
  1837.    short line, column;
  1838.  
  1839.    for (line=1; line < YSIZE; line++) {
  1840.       for (column=1; column < XSIZE+1; column++)
  1841.          switch(field[line][column]) {
  1842.             case 0:
  1843.                Draw_Box(column, line, 0, FALSE, RightOrLeft);
  1844.                break;
  1845.             case 1:
  1846.                Draw_Box(column, line, 1, TRUE, RightOrLeft);
  1847.                break;
  1848.             case 2:
  1849.                Draw_Box(column, line, 2, TRUE, RightOrLeft);
  1850.                break;
  1851.             case 3:
  1852.                Draw_Box(column, line, 3, TRUE, RightOrLeft);
  1853.                break;
  1854.             case 4:
  1855.                Draw_Box(column, line, 4, TRUE, RightOrLeft);
  1856.                break;
  1857.             case 5:
  1858.                Draw_Box(column, line, 5, TRUE, RightOrLeft);
  1859.                break;
  1860.             case 6:
  1861.                Draw_Box(column, line, 6, TRUE, RightOrLeft);
  1862.                break;
  1863.             case 7:
  1864.                Draw_Box(column, line, 7, TRUE, RightOrLeft);
  1865.                break;
  1866.          }
  1867.    }
  1868. }
  1869.  
  1870.  
  1871.  
  1872. void HideField(void)
  1873. {
  1874.    SetAPen(rp, 0);
  1875.    RectFill(rp, MAINXOFFSET+16, YOFFSET-1, MAINXOFFSET+16 + (XSIZE+1)*boxxsize-15, YOFFSET + YSIZE*boxysize+1);
  1876.  
  1877.    if (UseLace)
  1878.       DrawImage(rp, &Pausebrush, 190, 150);
  1879.    else
  1880.       DrawImage(rp, &Pausebrush, 310, 85);
  1881.  
  1882.    if (TwoPlayer) {
  1883.       RectFill(rp, MAINXOFFSET+16  + XSIZE*boxxsize + FieldsSpace, YOFFSET-1, MAINXOFFSET+16 + (XSIZE+1)*boxxsize-15 + XSIZE*boxxsize + FieldsSpace, YOFFSET + YSIZE*boxysize+1);
  1884.  
  1885.       if (UseLace)
  1886.          DrawImage(rp, &Pausebrush, 190 + XSIZE*boxxsize + FieldsSpace, 150);
  1887.       else
  1888.          DrawImage(rp, &Pausebrush, 310 + XSIZE*boxxsize + FieldsSpace, 85);
  1889.    }
  1890. }
  1891.